/**
 * 在线协作编辑器页面
 * 支持多人实时协作编辑、历史版本管理、评论功能
 */
import React, { useState, useEffect, useRef, useCallback, memo } from 'react';
import { useLocation } from 'react-router-dom';
import Quill from 'quill';
import 'quill/dist/quill.snow.css';
import * as Y from 'yjs';
import { QuillBinding } from 'y-quill';
import { SocketIOProvider } from '@/utils/yjs-socket-provider';
import io, { Socket } from 'socket.io-client';
import { MessageSquare, History, Users, FileText, Save } from 'lucide-react';
import { Button, Badge, Tooltip, message, Drawer, List, Avatar, Input as AntInput, Modal, Switch } from 'antd';
import { documentAPI, HistoryVersion, Comment, OnlineUser as OnlineUserType, DocumentNode } from '@/utils/api';
import { useThemeStore } from '@/stores/themeStore';
import { getUserInfo as getStoredUserInfo, StoredUserInfo, ensureSessionUserId } from '@/utils/auth';
import SheetEditor from './components/SheetEditor';
import SlideEditor from './components/SlideEditor';
import MindmapEditor from './components/MindmapEditor';

interface EditLog {
  id: string;
  user: string;
  action: string;
  content: string;
  time: string;
}

const DocumentCollab: React.FC = () => {
  // 功能开关：所有功能已启用，使用真实后端 API
  const ENABLE_HISTORY_API = true;
  const ENABLE_COMMENTS_API = true;
  const ENABLE_ONLINE_API = true;
  const ENABLE_UNDO_REDO = true; // 启用撤销/重做功能
  const ENABLE_SEARCH = true; // 启用内容搜索功能
  const ENABLE_EXPORT = true; // 启用文档导出功能
  
  // 自动保存功能状态 - 默认关闭，让用户决定是否开启
  // 从localStorage读取设置，如果没有则默认为false
  const [ENABLE_AUTO_SAVE, setEnableAutoSave] = useState(() => {
    try {
      const saved = localStorage.getItem('document_auto_save');
      return saved ? JSON.parse(saved) : false;
    } catch (error) {
      console.warn('读取自动保存设置失败:', error);
      return false;
    }
  });
  // 获取URL参数
  const location = useLocation();
  
  // WebSocket相关（保留用于在线用户和评论）
  const socketRef = useRef<Socket | null>(null);
  const [wsConnected, setWsConnected] = useState(false);
  
  // Yjs相关
  const ydocRef = useRef<Y.Doc | null>(null);
  const ytextRef = useRef<Y.Text | null>(null);
  const providerRef = useRef<SocketIOProvider | null>(null);
  const bindingRef = useRef<QuillBinding | null>(null);
  const saveTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  
  // 编辑器相关状态
  const [quill, setQuill] = useState<Quill | null>(null);
  const editorRef = useRef<HTMLDivElement>(null);
  const quillInitializedRef = useRef<boolean>(false); // 标记是否已初始化
  const [documentData, setDocumentData] = useState<{ id: string; name: string; content: string; docType?: string } | null>(null);
  const [loading, setLoading] = useState(true);
  const [documentId, setDocumentId] = useState<string>('');
  // 新增功能状态
  const [lastSavedTime, setLastSavedTime] = useState<string>('从未保存');
  const [autoSaveTimer, setAutoSaveTimer] = useState<NodeJS.Timeout | null>(null);
  const [searchTerm, setSearchTerm] = useState<string>('');
  const [searchResults, setSearchResults] = useState<{ index: number; text: string }[]>([]);
  const [currentSearchIndex, setCurrentSearchIndex] = useState<number>(-1);
  const [isSearching, setIsSearching] = useState<boolean>(false);
  const [offlineMode, setOfflineMode] = useState<boolean>(false); // 离线编辑模式
  
  // 获取当前用户信息
  const getCurrentUserInfo = (): StoredUserInfo | null => {
    try {
      return getStoredUserInfo();
    } catch {
      return null;
    }
  };
  
  // 当前用户信息
const currentUserId = useRef<string>(`user_${Date.now()}`);
const currentUserBaseId = useRef<string>(`user_${Date.now()}`);
  const currentUserName = useRef<string>('我');
  const currentUserColor = useRef<string>('bg-indigo-500');
const currentSessionId = useRef<string>(ensureSessionUserId());
  
  const joinDocumentRoom = useCallback(() => {
    if (!documentId || !socketRef.current) {
      console.log('[DocumentCollab] 无法加入文档房间：缺少documentId或socket引用');
      return;
    }
    
    const socket = socketRef.current;
    const baseId = currentUserBaseId.current;
    const sessionId = currentSessionId.current;
    const compositeId = `${baseId}:${sessionId}`;
    currentUserId.current = compositeId;

    // 确保socket已连接再发送
    if (socket.connected) {
      console.log(`[DocumentCollab] 发送join-document事件，文档ID: ${documentId}`);
      socket.emit('join-document', {
        documentId,
        userId: baseId,
        sessionId,
        userName: currentUserName.current,
        avatar: currentUserName.current.charAt(0),
        color: currentUserColor.current
      });
    } else {
      console.warn('[DocumentCollab] Socket未连接，等待连接后再发送join-document');
      // 监听连接事件后再发送
      const handleConnect = () => {
        socket.emit('join-document', {
          documentId,
          userId: baseId,
          sessionId,
          userName: currentUserName.current,
          avatar: currentUserName.current.charAt(0),
          color: currentUserColor.current
        });
        // 移除临时监听器，避免多次触发
        socket.off('connect', handleConnect);
      };
      socket.once('connect', handleConnect);
      
      // 5秒后移除监听器，避免内存泄漏
      setTimeout(() => {
        socket.off('connect', handleConnect);
      }, 5000);
    }
  }, [documentId, currentUserName, currentUserColor]);

  // 移除重复的在线用户刷新逻辑，保留下面的5秒更新版本
  
  // 初始化并监听用户信息变化
  useEffect(() => {
    const updateUserInfo = () => {
      const userInfo = getCurrentUserInfo();
      if (userInfo) {
        const baseId =
          (userInfo.id !== undefined ? String(userInfo.id) : undefined) ||
          userInfo.username ||
          userInfo.email ||
          currentUserBaseId.current;

        const sessionId = userInfo.sessionId || currentSessionId.current || ensureSessionUserId();

        const normalizedId = `${baseId}:${sessionId}`;

        const normalizedName =
          userInfo.displayName ||
          userInfo.username ||
          userInfo.email ||
          '我';

        currentUserBaseId.current = baseId;
        currentSessionId.current = sessionId;
        currentUserId.current = normalizedId;
        currentUserName.current = normalizedName;
        
        // 如果socket已连接，重新发送用户信息
        if (socketRef.current && socketRef.current.connected && documentId) {
          joinDocumentRoom();
        }
      }
    };
    
    // 初始更新用户信息
    updateUserInfo();
    
    // 添加storage事件监听器，监听localStorage变化
    const handleStorageChange = (e: StorageEvent) => {
      if (e.key === 'userInfo' || e.key === 'user_info') {
        updateUserInfo();
      }
    };
    
    window.addEventListener('storage', handleStorageChange);
    
    return () => {
      window.removeEventListener('storage', handleStorageChange);
    };
  }, [documentId, joinDocumentRoom]);
  
  // 在线用户相关状态
  const [onlineUsers, setOnlineUsers] = useState<OnlineUserType[]>([]);
  const [showOnlineUsers, setShowOnlineUsers] = useState(false);
  const [editLogs, setEditLogs] = useState<EditLog[]>([]);
  const [saving, setSaving] = useState(false);
  const [historyVersions, setHistoryVersions] = useState<HistoryVersion[]>([]);
  const [comments, setComments] = useState<Comment[]>([]);
  const [commentInput, setCommentInput] = useState('');
  const [replyTo, setReplyTo] = useState<string | null>(null);
const [editingCommentId, setEditingCommentId] = useState<string | null>(null);
const [editingCommentContent, setEditingCommentContent] = useState('');
const [showEditCommentModal, setShowEditCommentModal] = useState(false);
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [selectedVersion, setSelectedVersion] = useState<HistoryVersion | null>(null);
  const [restoringVersion, setRestoringVersion] = useState<string | null>(null);
  const [showHistory, setShowHistory] = useState(false);
  const [showComments, setShowComments] = useState(false);

  const addLog = useCallback((user: string, action: string, isRemote = false) => {
    const newLog: EditLog = {
      id: Date.now().toString(),
      user,
      action,
      content: action,
      time: new Date().toLocaleTimeString()
    };
    
    // 更新本地日志状态
    setEditLogs(prev => [newLog, ...prev].slice(0, 8));
    
    // 如果是本地操作且有socket连接，广播日志给其他用户
    if (!isRemote && socketRef.current && socketRef.current.connected && documentId) {
      socketRef.current.emit('log-updated', {
        documentId,
        log: newLog
      });
    }
  }, [documentId]);

  // 定期更新在线用户状态（从后端获取）
  useEffect(() => {
    if (!documentId || !ENABLE_ONLINE_API) return;
    
    const updateOnlineUsers = async () => {
      try {
        console.log('正在获取在线用户列表，文档ID:', documentId);
        const usersResponse = await documentAPI.getOnlineUsers(documentId);
        const usersApiResponse = usersResponse as unknown as { success?: boolean; data?: OnlineUserType[]; code?: number };
        
        console.log('在线用户API响应:', usersApiResponse);
        if (usersApiResponse.success && usersApiResponse.data) {
          // 使用函数式更新，合并轮询结果和 WebSocket 事件的结果
          setOnlineUsers(prev => {
            // 创建一个以 compositeId 为 key 的映射，优先使用最新的数据
            const userMap = new Map<string, OnlineUserType>();
            
            // 先添加轮询获取的最新数据
            usersApiResponse.data!.forEach(u => {
              const user = u as OnlineUserType & { userId?: string; sessionId?: string };
              const compositeId = user.id || (user.userId && user.sessionId ? `${user.userId}:${user.sessionId}` : user.userId || '');
              if (compositeId) {
                userMap.set(compositeId, u);
              }
            });
            
            // 然后合并之前的状态（保留 WebSocket 事件更新的用户，如果轮询中没有）
            prev.forEach(u => {
              const user = u as OnlineUserType & { userId?: string; sessionId?: string };
              const compositeId = user.id || (user.userId && user.sessionId ? `${user.userId}:${user.sessionId}` : user.userId || '');
              if (compositeId && !userMap.has(compositeId)) {
                // 如果轮询中没有，但之前状态中有，检查是否应该保留
                // 这里保留，因为可能是 WebSocket 事件刚更新的
                userMap.set(compositeId, u);
              }
            });
            
            // 确保包含当前用户自己
            const currentCompositeId = currentUserId.current;
            const currentUserExists = Array.from(userMap.values()).some(u => {
              const user = u as OnlineUserType & { userId?: string; sessionId?: string };
              const compositeId = user.id || (user.userId && user.sessionId ? `${user.userId}:${user.sessionId}` : user.userId || '');
              return compositeId === currentCompositeId;
            });
            
            if (!currentUserExists) {
              userMap.set(currentCompositeId, {
                id: currentUserId.current,
                userId: currentUserBaseId.current,
                sessionId: currentSessionId.current,
                name: currentUserName.current,
                avatar: currentUserName.current.charAt(0),
                color: currentUserColor.current,
                cursorPosition: 0
              });
            }
            
            const usersToSet = Array.from(userMap.values());
            console.log('设置在线用户:', usersToSet);
            return usersToSet;
          });
        }
      } catch (error) {
        console.error('获取在线用户失败:', error);
      }
    };
    
    // 初始加载
    updateOnlineUsers();
    
    // 每 5 秒更新一次（与心跳间隔一致），减少轮询频率
    const interval = setInterval(updateOnlineUsers, 5000);
    
    return () => clearInterval(interval);
  }, [documentId, ENABLE_ONLINE_API]);

  // 简单的类型探测：用于没有 docType 的旧数据兜底
  const detectDocType = useCallback((content?: string): 'sheet' | 'slide' | 'mindmap' | undefined => {
    if (!content) return undefined;
    try {
      const parsed = JSON.parse(content);
      if (Array.isArray(parsed)) return 'sheet';
    } catch {
      // not json
    }
    const txt = content.trim();
    // slide: 有 --- 分页且包含 Markdown 标题
    if (/\n---\n/.test(txt) && /(^|\n)#{1,6}\s+/.test(txt)) return 'slide';
    // mindmap: Markdown 大纲（以 # 开头 或 存在多层级列表）
    if (/^#\s+/.test(txt) || /(^|\n)-\s+.+\n\s{2,}-\s+/.test(txt)) return 'mindmap';
    return undefined;
  }, []);

  // 从URL中获取文档ID并加载文档数据
  useEffect(() => {
    const getDocumentId = () => {
      const searchParams = new URLSearchParams(location.search);
      return searchParams.get('id');
    };

    const loadDocument = async () => {
       setLoading(true);
       try {
         const docId = getDocumentId();
         
         if (!docId) {
           addLog('系统', '未提供文档ID');
           setLoading(false);
           return;
         }
         
         setDocumentId(docId);
         
         // 从API加载文档
         const response = await documentAPI.getDocumentById(docId);
         // API 返回格式: { code: 200, success: true, data: DocumentNode }
         const apiResponse = response as unknown as { success?: boolean; data?: DocumentNode; code?: number };
         if (apiResponse.success && apiResponse.data) {
           const doc = apiResponse.data;
          setDocumentData({
             id: doc.id,
             name: doc.name,
             content: doc.content || '',
             // 旧数据没有 docType 时，尝试根据内容兜底推断一个，保证跳转编辑时选择正确组件
            docType: (doc as { docType?: string }).docType || detectDocType(doc.content || '')
           });
           addLog('系统', `加载文档：${doc.name}`);
           
          // 加载历史版本（可选）
          if (ENABLE_HISTORY_API) {
            const versionsResponse = await documentAPI.getDocumentVersions(docId);
            const versionsApiResponse = versionsResponse as unknown as { success?: boolean; data?: HistoryVersion[]; code?: number };
            if (versionsApiResponse.success && versionsApiResponse.data) {
              setHistoryVersions(versionsApiResponse.data);
            }
          }
          
          // 加载评论（可选）
          if (ENABLE_COMMENTS_API) {
            const commentsResponse = await documentAPI.getDocumentComments(docId);
            const commentsApiResponse = commentsResponse as unknown as { success?: boolean; data?: Comment[]; code?: number };
            if (commentsApiResponse.success && commentsApiResponse.data) {
              setComments(commentsApiResponse.data);
            }
          }
          
          // 加载在线用户（可选）
          if (ENABLE_ONLINE_API) {
            const usersResponse = await documentAPI.getOnlineUsers(docId);
            const usersApiResponse = usersResponse as unknown as { success?: boolean; data?: OnlineUserType[]; code?: number };
            if (usersApiResponse.success && usersApiResponse.data) {
              setOnlineUsers(usersApiResponse.data);
            }
          }
         } else {
           addLog('系统', '文档不存在');
         }
       } catch (error) {
         console.error('加载文档失败:', error);
         addLog('系统', '加载文档失败');
       } finally {
         setLoading(false);
       }
     };

    loadDocument();
  }, [location.search, addLog, detectDocType, ENABLE_HISTORY_API, ENABLE_COMMENTS_API, ENABLE_ONLINE_API]);

  // 初始化WebSocket连接
  useEffect(() => {
    if (!documentId) return;
    
    let reconnectTimer: NodeJS.Timeout | null = null;
    let heartbeatTimer: NodeJS.Timeout | null = null;
    const maxReconnectAttempts = 5;
    let reconnectAttempts = 0;
    
    // 连接WebSocket服务器
    const wsUrl = import.meta.env.VITE_WS_URL || 'http://localhost:3000';
    const socket = io(wsUrl, {
      transports: ['websocket', 'polling'],
      reconnection: true,
      reconnectionAttempts: maxReconnectAttempts,
      reconnectionDelay: 1000,
      reconnectionDelayMax: 5000,
      timeout: 20000
    });
    
    socketRef.current = socket;
    
    // 发送心跳保持连接
    const startHeartbeat = () => {
      if (heartbeatTimer) {
        clearInterval(heartbeatTimer);
      }
      heartbeatTimer = setInterval(() => {
        if (socket.connected) {
          socket.emit('heartbeat', {
            documentId,
            userId: currentUserBaseId.current,
            sessionId: currentSessionId.current
          });
        }
      }, 30000); // 每30秒发送一次心跳
    };
    
    // 停止心跳
    const stopHeartbeat = () => {
      if (heartbeatTimer) {
        clearInterval(heartbeatTimer);
        heartbeatTimer = null;
      }
    };
    
    // 重新加入文档
    const rejoinDocument = () => {
      if (!documentId) {
        console.warn('[DocumentCollab] 无法重新加入文档：缺少documentId');
        return;
      }
      
      console.log('[DocumentCollab] 尝试重新加入文档房间');
      
      // 确保socket连接
      if (!socket.connected) {
        console.log('[DocumentCollab] Socket未连接，尝试重连...');
        socket.connect();
        
        // 等待连接成功后再加入房间
        const handleConnect = () => {
          console.log('[DocumentCollab] Socket重连成功，现在加入文档房间');
          joinDocumentRoom();
          
          // 重新获取在线用户列表
          fetchOnlineUsers();
          
          // 移除临时监听器
          socket.off('connect', handleConnect);
        };
        
        socket.once('connect', handleConnect);
        
        // 10秒后超时处理
        setTimeout(() => {
          socket.off('connect', handleConnect);
          if (!socket.connected) {
            console.error('[DocumentCollab] Socket重连超时');
          }
        }, 10000);
      } else {
        // 已连接，直接加入房间
        joinDocumentRoom();
        fetchOnlineUsers();
      }
    };
    
    // 封装获取在线用户的函数
    const fetchOnlineUsers = () => {
      if (ENABLE_ONLINE_API && documentId) {
        documentAPI.getOnlineUsers(documentId)
          .then((usersResponse) => {
            const usersApiResponse = usersResponse as unknown as { success?: boolean; data?: OnlineUserType[]; code?: number };
            if (usersApiResponse.success && usersApiResponse.data) {
              console.log(`[DocumentCollab] 获取到${usersApiResponse.data.length}个在线用户`);
              setOnlineUsers(usersApiResponse.data);
            }
          })
          .catch((error) => {
            console.error('获取在线用户列表失败:', error);
            // 失败后重试一次
            setTimeout(() => {
              documentAPI.getOnlineUsers(documentId)
                .then((usersResponse) => {
                  const usersApiResponse = usersResponse as unknown as { success?: boolean; data?: OnlineUserType[]; code?: number };
                  if (usersApiResponse.success && usersApiResponse.data) {
                    setOnlineUsers(usersApiResponse.data);
                  }
                })
                .catch((retryError) => {
                  console.error('重试获取在线用户列表失败:', retryError);
                });
            }, 2000);
          });
      }
    };
    
    socket.on('connect', () => {
      console.log('WebSocket连接成功');
      setWsConnected(true);
      reconnectAttempts = 0;
      
      // 加入文档房间
      joinDocumentRoom();
      
      // 更新在线用户状态
      if (ENABLE_ONLINE_API && documentId) {
        documentAPI.updateOnlineUser(documentId, {
          userId: currentUserBaseId.current,
          sessionId: currentSessionId.current,
          userName: currentUserName.current,
          avatar: currentUserName.current.charAt(0),
          color: currentUserColor.current,
          cursorPosition: 0
        }).catch(err => {
          console.error('更新在线用户状态失败:', err);
        });
      }
      
      // 启动心跳
      startHeartbeat();
    });
    
    socket.on('disconnect', (reason) => {
      console.log('WebSocket断开连接，原因:', reason);
      setWsConnected(false);
      stopHeartbeat();
      
      // 如果不是手动断开，尝试重连
      if (reason !== 'io client disconnect') {
        if (reconnectAttempts < maxReconnectAttempts) {
          reconnectAttempts++;
          console.log(`尝试重连... (${reconnectAttempts}/${maxReconnectAttempts})`);
          // Socket.IO会自动尝试重连，但我们在这里添加额外的逻辑
          reconnectTimer = setTimeout(() => {
            if (socket) {
              socket.connect();
            }
          }, 1000 * reconnectAttempts);
        }
      }
    });
    
    socket.on('reconnect', (attemptNumber) => {
      console.log(`WebSocket重连成功，尝试次数: ${attemptNumber}`);
      setWsConnected(true);
      reconnectAttempts = 0;
      
      // 重新加入文档
      rejoinDocument();
      
      // 重新启动心跳
      startHeartbeat();
    });
    
    socket.on('reconnect_failed', () => {
      console.log('WebSocket重连失败');
    });
    
    socket.on('heartbeat-response', () => {
      console.log('收到心跳响应');
    });
    
    socket.on('user-joined', (data) => {
      console.log('用户加入:', data);
      addLog(data.userName, '加入了文档');
      
      // 如果后端提供了完整的在线用户列表，使用它
      if (data.onlineUsers && Array.isArray(data.onlineUsers)) {
        setOnlineUsers(prev => {
          // 合并后端列表和当前状态，去重
          const userMap = new Map<string, OnlineUserType>();
          
          // 先添加后端提供的列表
          data.onlineUsers.forEach((u: OnlineUserType) => {
            const user = u as OnlineUserType & { userId?: string; sessionId?: string };
            const compositeId = user.id || (user.userId && user.sessionId ? `${user.userId}:${user.sessionId}` : user.userId || '');
            if (compositeId) {
              userMap.set(compositeId, u);
            }
          });
          
          // 然后合并之前的状态（保留可能的新用户）
          prev.forEach(u => {
            const user = u as OnlineUserType & { userId?: string; sessionId?: string };
            const compositeId = user.id || (user.userId && user.sessionId ? `${user.userId}:${user.sessionId}` : user.userId || '');
            if (compositeId && !userMap.has(compositeId)) {
              userMap.set(compositeId, u);
            }
          });
          
          return Array.from(userMap.values());
        });
      } else {
        // 如果没有提供完整列表，只添加新用户
        setOnlineUsers(prev => {
          const newUser: OnlineUserType = {
            id: data.userId as string,
            userId: data.baseUserId as string,
            sessionId: data.sessionId as string,
            name: data.userName as string,
            avatar: data.avatar as string,
            color: data.color as string,
            cursorPosition: 0
          };
          
          // 检查是否已存在
          const exists = prev.some(u => {
            const user = u as OnlineUserType & { userId?: string; sessionId?: string };
            const compositeId = user.id || (user.userId && user.sessionId ? `${user.userId}:${user.sessionId}` : user.userId || '');
            return compositeId === newUser.id;
          });
          
          return exists ? prev : [...prev, newUser];
        });
      }
    });
    
    socket.on('user-left', (data) => {
      console.log('用户离开:', data);
      addLog(data.userName, '离开了文档');
      const leftCompositeId = data.userId as string | undefined;
      const leftBaseId = (data.baseUserId as string | undefined) || undefined;
      const leftSessionId = data.sessionId as string | undefined;
      
      setOnlineUsers(prev =>
        prev.filter(u => {
          const user = u as OnlineUserType & { userId?: string; sessionId?: string };
          const compositeId =
            user.id ||
            (user.userId && user.sessionId ? `${user.userId}:${user.sessionId}` : user.userId || '');
          
          // 优先使用 compositeId 匹配
          if (leftCompositeId && compositeId === leftCompositeId) {
            return false;
          }
          
          // 如果没有 sessionId，使用 baseUserId 匹配（兼容旧逻辑）
          if (leftBaseId && user.userId === leftBaseId) {
            if (!leftSessionId) {
              // 如果没有 sessionId，删除所有匹配 baseUserId 的用户
              return false;
            }
            // 如果有 sessionId，只删除匹配 sessionId 的用户
            if (user.sessionId && user.sessionId === leftSessionId) {
              return false;
            }
          }
          
          return true;
        })
      );
    });
    
    // 注意：document-change事件已由Yjs处理，这里保留用于日志记录
    // socket.on('document-change', (data) => {
    //   // Yjs会自动处理文档同步，这里不再需要手动处理
    // });
    
    socket.on('cursor-change', (data) => {
      console.log('收到光标变更:', data);
      // 可以在这里实现光标显示逻辑
    });
    
    socket.on('comment-added', (data) => {
      console.log('收到新评论:', data);
      if (data.comment) {
        // 检查评论是否已存在，避免重复添加
        setComments(prev => {
          // 首先检查是否已存在（无论是顶级评论还是回复）
          const existsAsTopLevel = prev.some(c => c.id === data.comment.id);
          const existsAsReply = prev.some(comment => {
            return comment.replies?.some(r => r.id === data.comment.id);
          });
          
          if (existsAsTopLevel || existsAsReply) {
            console.log('评论已存在，跳过添加:', data.comment.id);
            return prev;
          }
          
          // 如果是回复，需要添加到对应评论的replies中
          if (data.comment.parentId) {
            // 查找父评论
            const parentComment = prev.find(c => c.id === data.comment.parentId);
            if (parentComment) {
              // 添加到对应评论的replies中
              return prev.map(comment => {
                if (comment.id === data.comment.parentId) {
                  return {
                    ...comment,
                    replies: [...(comment.replies || []), data.comment]
                  };
                }
                return comment;
              });
            } else {
              // 父评论不存在，可能是数据还没加载，暂时跳过
              console.log('父评论不存在，跳过添加回复:', data.comment.id);
              return prev;
            }
          }
          
          // 新评论，添加到列表开头
          return [data.comment, ...prev];
        });
      }
    });
    
    socket.on('comment-updated', (data) => {
      console.log('收到评论更新:', data);
      if (data.comment) {
        setComments(prev => prev.map(c => c.id === data.comment.id ? data.comment : c));
      }
    });
    
    socket.on('comment-deleted', (data) => {
      console.log('收到评论删除:', data);
      if (data.commentId) {
        setComments(prev => prev.filter(c => c.id !== data.commentId));
      }
    });
    
    // 监听远程日志更新
    socket.on('log-updated', (data) => {
      console.log('收到远程日志更新:', data);
      if (data.log) {
        // 使用isRemote标志添加日志，避免循环广播
        addLog(data.log.user, data.log.action, true);
      }
    });
    
    // 保存socket引用
    socketRef.current = socket;
    
    return () => {
      // 清理定时器
      if (reconnectTimer) {
        clearTimeout(reconnectTimer);
      }
      if (heartbeatTimer) {
        clearInterval(heartbeatTimer);
      }
      
      // 清理WebSocket连接
      if (socket) {
        // 移除事件监听器
        socket.off('log-updated');
        
        // 主动离开文档房间，通知其他用户
        if (socket.connected && documentId) {
          socket.emit('leave-document', {
            documentId,
            userId: currentUserBaseId.current,
            sessionId: currentSessionId.current
          });
        }
        socket.disconnect();
      }
    };
  }, [documentId, quill, addLog, ENABLE_ONLINE_API, joinDocumentRoom]);
  
  // 初始化Quill编辑器（使用Yjs和OT算法）
  useEffect(() => {
    let cleanup: (() => void) | undefined;
    let reconnectTimer: NodeJS.Timeout | null = null;
    let initRetryCount = 0;
    const MAX_INIT_RETRIES = 3;
    
    // 只有当文档数据加载完成且编辑器容器存在且未初始化时才初始化编辑器
    if (editorRef.current && !quillInitializedRef.current && documentData && !loading && documentId) {
      // 增强的WebSocket连接处理
      const ensureConnectionAndInit = () => {
        // 检查WebSocket连接状态，如果未连接则等待连接后再初始化Yjs
        if (socketRef.current && !socketRef.current.connected) {
          console.log('[Yjs] WebSocket未连接，等待连接后再初始化...');
          
          // 尝试主动重连
          if (socketRef.current) {
            socketRef.current.connect();
          }
          
          // 监听连接事件，连接成功后再初始化
          const handleConnect = () => {
            console.log('[Yjs] WebSocket已连接，开始初始化编辑器...');
            cleanup = initEditor();
          };
          
          // 监听连接错误
          const handleConnectError = (error: Error) => {
            console.error('[Yjs] WebSocket连接错误:', error);
            
            // 尝试重连
            initRetryCount++;
            if (initRetryCount <= MAX_INIT_RETRIES) {
              console.log(`[Yjs] 尝试重新连接 (${initRetryCount}/${MAX_INIT_RETRIES})...`);
              
              // 指数退避策略
              reconnectTimer = setTimeout(() => {
                if (socketRef.current) {
                  socketRef.current.connect();
                }
              }, 2000 * initRetryCount);
            } else {
              console.error('[Yjs] 连接重试次数已达上限，使用离线模式...');
              // 即使连接失败，也尝试初始化编辑器（离线模式）
              cleanup = initEditor(true);
              socketRef.current?.off('connect', handleConnect);
              socketRef.current?.off('connect_error', handleConnectError);
            }
          };
          
          socketRef.current.once('connect', handleConnect);
          socketRef.current.once('connect_error', handleConnectError);
          
          return () => {
            if (socketRef.current) {
              socketRef.current.off('connect', handleConnect);
              socketRef.current.off('connect_error', handleConnectError);
            }
            if (reconnectTimer) {
              clearTimeout(reconnectTimer);
            }
            if (cleanup) {
              cleanup();
            }
          };
        } else {
          // WebSocket已连接或不存在，直接初始化
          cleanup = initEditor();
        }
      };
      
      return ensureConnectionAndInit();
    }
    
    return () => {
      if (reconnectTimer) {
        clearTimeout(reconnectTimer);
      }
      if (cleanup) {
        cleanup();
      }
    };
    
    function initEditor(isOfflineMode = false) {
      try {
        // 在初始化前，先清理可能存在的工具栏和编辑器实例
        const container = editorRef.current;
        if (!container) return () => {};
        
        // 清理可能存在的工具栏（可能在父元素中）
        const existingToolbars = container.parentNode?.querySelectorAll('.ql-toolbar');
        if (existingToolbars && existingToolbars.length > 0) {
          existingToolbars.forEach(toolbar => toolbar.remove());
        }
        
        // 清理容器内可能存在的Quill实例
        if (container.querySelector('.ql-container')) {
          container.innerHTML = '';
        }
        
        // 清理之前的Yjs资源
        if (bindingRef.current) {
          bindingRef.current.destroy();
          bindingRef.current = null;
        }
        if (providerRef.current) {
          providerRef.current.destroy();
          providerRef.current = null;
        }
        if (ydocRef.current) {
          ydocRef.current.destroy();
          ydocRef.current = null;
        }
        
        // 清理自动保存定时器
        if (saveTimeoutRef.current) {
          clearTimeout(saveTimeoutRef.current);
          saveTimeoutRef.current = null;
        }
        
        // 标记为已初始化，防止重复初始化
        quillInitializedRef.current = true;
        
        // 创建Yjs文档
        const ydoc = new Y.Doc();
        ydocRef.current = ydoc;
        
        // 创建Y.Text（用于存储Quill富文本内容）
        // 注意：QuillBinding 使用 Y.Text，它会自动处理 Quill 的 Delta 格式
        const ytext = ydoc.getText('content');
        ytextRef.current = ytext;
        
        // 使用snow主题创建Quill编辑器，启用撤销/重做功能
        const newQuill = new Quill(container, {
          theme: 'snow',
          placeholder: '开始编辑文档...',
          modules: {
            history: {
              delay: 1000, // 操作合并延迟
              maxStack: 100, // 最大历史记录栈深度
              userOnly: true // 仅记录用户操作
            }
          }
        });
        
        // 注册键盘快捷键
        if (ENABLE_UNDO_REDO) {
          // 撤销：Ctrl+Z
          newQuill.keyboard.addBinding({
            key: 'Z',
            shortKey: true
          }, () => {
            newQuill.history.undo();
            return false;
          });
          
          // 重做：Ctrl+Y
          newQuill.keyboard.addBinding({
            key: 'Y',
            shortKey: true
          }, () => {
            newQuill.history.redo();
            return false;
          });
        }
        
        setQuill(newQuill);
        
        // 创建SocketIOProvider（用于Yjs同步）
        let provider: SocketIOProvider | null = null;
        
        if (!isOfflineMode) {
          // 复用现有的 Socket.io 连接，避免创建多个连接
          const wsUrl = import.meta.env.VITE_WS_URL || 'http://localhost:3000';
          const existingSocket = socketRef.current;
          
          // 确保传入的socket已经连接，如果未连接则等待
          if (existingSocket && existingSocket.connected) {
            console.log('[Yjs] 使用已连接的Socket创建Provider');
          } else if (existingSocket) {
            console.log('[Yjs] Socket存在但未连接，尝试创建Provider');
          }
          
          try {
            provider = existingSocket 
              ? new SocketIOProvider(existingSocket, documentId, ydoc, {
                  awareness: true // 启用awareness，用于显示其他用户的光标位置
                })
              : new SocketIOProvider(wsUrl, documentId, ydoc, {
                  awareness: true // 启用awareness，用于显示其他用户的光标位置
                });
            providerRef.current = provider;
            
            // 增强的同步状态监控
            let syncTimeout: NodeJS.Timeout | null = null;
            const SYNC_TIMEOUT_MS = 5000; // 5秒同步超时
            
            // 监听Yjs同步状态
            provider.on('synced', () => {
              console.log('[Yjs] ✅ 文档已同步成功');
              setWsConnected(true);
              
              // 清除同步超时定时器
              if (syncTimeout) {
                clearTimeout(syncTimeout);
                syncTimeout = null;
              }
              
              addLog('系统', '文档同步成功，协作编辑已就绪');
            });
            
            provider.on('status', (event: { status?: string }) => {
              console.log('[Yjs] 状态更新:', event);
              if (event.status === 'connected') {
                setWsConnected(true);
              } else if (event.status === 'disconnected') {
                setWsConnected(false);
                addLog('系统', '连接已断开，切换到离线模式');
              }
            });
            
            // 添加同步错误处理
            provider.on('error', (error: any) => {
              console.error('[Yjs] 同步错误:', error);
              setWsConnected(false);
              addLog('系统', `同步错误: ${error.message || '未知错误'}`);
            });
            
            // 设置同步超时
            syncTimeout = setTimeout(() => {
              console.warn('[Yjs] ⚠️ 同步超时，尝试重新同步...');
              addLog('系统', '同步超时，尝试重新连接');
              
              // 尝试重新同步
              if (provider && provider.syncProtocolHandler) {
                // 强制重新同步
                try {
                  provider.syncProtocolHandler.connect();
                } catch (err) {
                  console.error('[Yjs] 重连失败:', err);
                }
              }
            }, SYNC_TIMEOUT_MS);
          } catch (providerError) {
            console.error('[Yjs] 创建Provider失败:', providerError);
            addLog('系统', '无法创建同步连接，使用离线模式');
            isOfflineMode = true;
          }
        }
        
        if (isOfflineMode) {
          console.log('[Yjs] 进入离线模式，无法同步');
          setWsConnected(false);
          addLog('系统', '当前处于离线模式，编辑内容不会同步');
          
          // 创建一个空的Awareness对象
          const awareness = new Awareness(ydoc);
          
          // 设置本地用户信息
          awareness.setLocalStateField('user', {
            name: currentUserName.current,
            color: currentUserColor.current,
            avatar: currentUserName.current.charAt(0)
          });
          
          // 创建一个模拟的provider对象，只包含awareness
          provider = {
            awareness,
            destroy: () => {},
            on: () => {},
            off: () => {},
            disconnect: () => {},
            connect: () => {}
          } as any;
        }
      
      // 在创建 QuillBinding 之前，先设置用户信息到 Awareness
      // 这样 QuillBinding 才能正确显示光标位置
      if (provider.awareness) {
        provider.awareness.setLocalStateField('user', {
          name: currentUserName.current,
          color: currentUserColor.current,
          avatar: currentUserName.current.charAt(0),
          clientId: provider.awareness.clientID,
          connectedAt: Date.now()
        });
        console.log('[Yjs] 已设置本地用户 Awareness 状态（在创建 QuillBinding 之前）');
      }
      
      // 设置初始内容（从数据库加载的内容）
      // 注意：在创建 QuillBinding 之前设置内容，使用 'silent' 模式避免触发同步
      if (documentData.content) {
        try {
          // 使用 Quill 的 Delta 格式设置内容
          const delta = newQuill.clipboard.convert({ html: documentData.content });
          // 使用 'silent' 模式设置，避免触发 QuillBinding 同步
          newQuill.setContents(delta, 'silent');
          console.log('[Yjs] 已设置初始内容到 Quill（silent 模式）');
        } catch (error) {
          console.error('[Yjs] 设置初始内容失败:', error);
          // 降级方案：直接使用 HTML 内容
          try {
            newQuill.root.innerHTML = documentData.content;
            console.log('[Yjs] 降级方案：直接设置 innerHTML 成功');
          } catch (fallbackError) {
            console.error('[Yjs] 降级设置内容也失败:', fallbackError);
          }
        }
      }
      
      // 创建QuillBinding（绑定Quill和Yjs）
      // 注意：QuillBinding会自动同步 Quill 和 Yjs 之间的内容
      // 第三个参数是Awareness，用于显示其他用户的光标位置
      // 重要：在设置内容之后创建 QuillBinding，这样它可以从 Quill 同步到 Yjs
      console.log('[Yjs] 创建 QuillBinding...');
      console.log('[Yjs] Quill 当前长度:', newQuill.getLength());
      console.log('[Yjs] Yjs Text 当前长度:', ytext.length);
      
      const binding = new QuillBinding(ytext, newQuill, provider.awareness || undefined);
      bindingRef.current = binding;
      console.log('[Yjs] QuillBinding 创建完成（已启用 Awareness）');
      
      // 优化的同步检查机制
      const syncCheckInterval = setInterval(() => {
        const quillLength = newQuill.getLength();
        const ytextLength = ytext.length;
        console.log('[Yjs] 定期同步检查 - Quill 长度:', quillLength, 'Yjs 长度:', ytextLength);
        
        // 如果长度差异较大，尝试重新同步
        if (Math.abs(quillLength - ytextLength) > 50) {
          console.warn('[Yjs] ⚠️ Quill 和 Yjs 内容长度差异过大，重新同步...');
          try {
            // 获取当前内容并强制同步
            const currentContent = newQuill.root.innerHTML;
            if (currentContent) {
              const delta = newQuill.clipboard.convert({ html: currentContent });
              newQuill.setContents(delta, 'user');
              console.log('[Yjs] ✅ 已强制重新同步内容');
            }
          } catch (syncError) {
            console.error('[Yjs] 强制同步失败:', syncError);
          }
        }
      }, 10000); // 每10秒检查一次
      
      // QuillBinding 创建后，它会自动同步 Quill 的当前内容到 Yjs
      // 但是，如果 Quill 有内容而 Yjs 是空的，可能需要手动触发一次同步
      setTimeout(() => {
        const quillLength = newQuill.getLength();
        const ytextLength = ytext.length;
        console.log('[Yjs] 创建后检查 - Quill 长度:', quillLength, 'Yjs 长度:', ytextLength);
        
        // 如果 Quill 有内容但 Yjs 是空的，手动触发一次同步
        if (quillLength > 1 && ytextLength === 0) {
          console.log('[Yjs] ⚠️ Quill 有内容但 Yjs 为空，手动触发同步...');
          // 通过触发一次文本变化来让 QuillBinding 同步
          const currentContent = newQuill.root.innerHTML;
          if (currentContent) {
            // 使用非 silent 模式重新设置内容，触发 QuillBinding 同步
            const delta = newQuill.clipboard.convert({ html: currentContent });
            newQuill.setContents(delta, 'user');
            console.log('[Yjs] ✅ 已手动触发 QuillBinding 同步');
          }
        }
      }, 500); // 延迟500ms，确保 QuillBinding 初始化完成
      
      // 兜底：若当前编辑器仍为空，再次写入一次以避免某些情况下 convert 结果为空导致的空白
      if (documentData.content) {
        try {
          const length = newQuill.getLength();
          if (length <= 1) {
            newQuill.clipboard.dangerouslyPasteHTML(documentData.content, 'silent');
            console.log('[Quill] 使用 dangerouslyPasteHTML 兜底写入初始内容');
          }
        } catch (e) {
          console.warn('[Quill] 兜底写入初始内容失败:', e);
        }
      }
      
      // 监听文本变化事件（用于日志记录）
      newQuill.on('text-change', (delta, _oldDelta, source) => {
        // Yjs会自动处理同步，这里只用于日志
        if (source === 'user') {
          addLog(currentUserName.current, '编辑了文档内容');
          console.log('[Yjs] Quill 内容变化（user），delta:', delta);
          console.log('[Yjs] 应该触发 Yjs 更新，由 QuillBinding 处理');
        } else if (source === 'api') {
          console.log('[Yjs] Quill 内容变化（api），delta:', delta);
        } else {
          console.log('[Yjs] Quill 内容变化（其他），source:', source, 'delta:', delta);
        }
      });
      
      // 监听 Yjs 更新（用于调试和自动保存）
      let lastSaveTime = Date.now();
      const AUTO_SAVE_INTERVAL = 3000; // 3秒自动保存一次
      let pendingChanges = false;
      
      // 增强的Yjs更新处理
      const handleYjsUpdate = (update: Uint8Array, origin: unknown) => {
        console.log('[Yjs] Yjs 文档更新，origin:', origin, 'update size:', update.length);
        
        // 标记有未保存的更改
        pendingChanges = true;
        
        // 检查 origin 类型
        if (origin === binding) {
          console.log('[Yjs] ✅ 更新来源于 QuillBinding（本地编辑）');
          
          // 触发自动保存（节流，避免频繁保存）
          const now = Date.now();
          if (now - lastSaveTime >= AUTO_SAVE_INTERVAL && ENABLE_AUTO_SAVE && documentId) {
            lastSaveTime = now;
            
            // 清除之前的保存定时器
            if (saveTimeoutRef.current) {
              clearTimeout(saveTimeoutRef.current);
            }
            
            // 使用防抖，延迟1秒保存，合并多次更新
            saveTimeoutRef.current = setTimeout(() => {
              if (newQuill && documentId) {
                const content = newQuill.root.innerHTML;
                documentAPI.updateDocument(documentId, { content })
                  .then(() => {
                    console.log('[Yjs] 自动保存成功');
                    setLastSavedTime(new Date().toLocaleTimeString());
                    pendingChanges = false; // 重置待保存标记
                  })
                  .catch(err => {
                    console.error('[Yjs] 自动保存失败:', err);
                    // 保存失败不重置标记，保持有未保存更改的状态
                  });
              }
            }, 1000);
          }
        } else if (origin === provider) {
          console.log('[Yjs] ✅ 更新来源于远程（其他用户编辑）');
          // 远程更新时也尝试保存，确保本地状态与服务器一致
          const now = Date.now();
          if (now - lastSaveTime >= AUTO_SAVE_INTERVAL * 2 && ENABLE_AUTO_SAVE && documentId) {
            // 远程更新保存的间隔可以稍长一些
            lastSaveTime = now;
            
            if (saveTimeoutRef.current) {
              clearTimeout(saveTimeoutRef.current);
            }
            
            saveTimeoutRef.current = setTimeout(() => {
              if (newQuill && documentId) {
                const content = newQuill.root.innerHTML;
                documentAPI.updateDocument(documentId, { content })
                  .then(() => {
                    console.log('[Yjs] 远程更新后自动保存成功');
                    setLastSavedTime(new Date().toLocaleTimeString());
                  })
                  .catch(err => {
                    console.error('[Yjs] 远程更新后自动保存失败:', err);
                  });
              }
            }, 1500);
          }
        } else {
          console.log('[Yjs] ℹ️ 更新来源于其他渠道');
        }
      };
      
      ydoc.on('update', handleYjsUpdate);
      
      // 恢复正常try-catch结构
      return () => {
        // 清理定时器
        if (syncCheckInterval) {
          clearInterval(syncCheckInterval);
        }
        
        // 清理用户信息更新定时器
        cleanupInterval();
        
        // 清理自动保存定时器
        if (autoSaveTimer) {
          clearInterval(autoSaveTimer);
        }
        if (saveTimeoutRef.current) {
          clearTimeout(saveTimeoutRef.current);
          saveTimeoutRef.current = null;
        }
        
        if (bindingRef.current) {
          bindingRef.current.destroy();
          bindingRef.current = null;
        }
        if (providerRef.current) {
          providerRef.current.destroy();
          providerRef.current = null;
        }
        if (ydocRef.current) {
          ydocRef.current.destroy();
          ydocRef.current = null;
        }
        if (newQuill) {
          // 移除Quill实例
          const quillContainer = newQuill.container;
          if (quillContainer) {
            const toolbar = quillContainer.parentNode?.querySelector('.ql-toolbar');
            if (toolbar) toolbar.remove();
            
            // 清空容器内容
            quillContainer.innerHTML = '';
          }
        }
        // 重置初始化标记
        quillInitializedRef.current = false;
      };
    } catch (error) {
      console.error('[Yjs] 初始化编辑器失败:', error);
      addLog('系统', '编辑器初始化失败，请刷新页面重试');
      quillInitializedRef.current = false;
      return () => {};
    }
      
  // 监听选择变化（光标位置）— 加节流，避免高频请求导致页面卡顿
  const lastCursorSendRef = { time: 0 };
  newQuill.on('selection-change', (range) => {
    // 更新 Awareness 的本地用户信息（轻量操作）
    if (provider.awareness) {
      provider.awareness.setLocalStateField('user', {
        name: currentUserName.current,
        color: currentUserColor.current,
        avatar: currentUserName.current.charAt(0)
      });
    }
    // 节流发送 socket 与 HTTP 更新（300ms）
    const now = Date.now();
    if (now - lastCursorSendRef.time < 300) return;
    lastCursorSendRef.time = now;
    if (range && socketRef.current && socketRef.current.connected) {
      const position = range.index;
      socketRef.current.emit('cursor-change', { documentId, position });
      if (ENABLE_ONLINE_API && documentId) {
        documentAPI.updateOnlineUser(documentId, {
          userId: currentUserBaseId.current,
          sessionId: currentSessionId.current,
          userName: currentUserName.current,
          avatar: currentUserName.current.charAt(0),
          color: currentUserColor.current,
          cursorPosition: position
        }).catch(err => {
          console.error('更新在线用户状态失败:', err);
        });
      }
    }
  });
      
  // 定期更新用户信息（确保其他用户能看到）— 降低频率，减轻压力
  const userInfoUpdateInterval = setInterval(() => {
        if (provider.awareness) {
          // 定期更新用户信息，确保 Awareness 状态保持活跃
          provider.awareness.setLocalStateField('user', {
            name: currentUserName.current,
            color: currentUserColor.current,
            avatar: currentUserName.current.charAt(0),
            lastUpdate: Date.now() // 添加时间戳，确保每次都是新值
          });
        }
  }, 10000); // 每10秒更新一次，避免高频触发
      
      // 清理定时器
      const cleanupInterval = () => {
        if (userInfoUpdateInterval) {
          clearInterval(userInfoUpdateInterval);
        }
      };
      
      // 监听 Awareness 变化，显示其他用户的光标位置
      // 注意：QuillBinding 会自动处理光标位置的显示，这里主要用于调试和日志
      if (provider.awareness) {
        const awareness = provider.awareness;
        
        // 确保用户信息已设置（虽然已经在创建 QuillBinding 之前设置了，这里再次确保）
        awareness.setLocalStateField('user', {
          name: currentUserName.current,
          color: currentUserColor.current,
          avatar: currentUserName.current.charAt(0)
        });
        
        awareness.on('change', (changes: { added: number[], updated: number[], removed: number[] }) => {
          console.log('[Yjs] Awareness 变化:', changes);
          
          // 获取所有用户的状态
          const states = awareness.getStates();
          const localClientId = awareness.clientID;
          
          console.log('[Yjs] 当前 Awareness 状态数:', states.size, '本地 clientID:', localClientId);
          
          // 遍历所有用户，显示他们的光标位置
          // QuillBinding 会自动处理光标位置的显示，这里只用于调试
          states.forEach((state, clientId) => {
            if (clientId !== localClientId) {
              const user = state.user as { name: string; color: string; avatar: string } | undefined;
              if (user) {
                console.log(`[Yjs] 用户 ${user.name} (clientID: ${clientId}) 在线`);
                // QuillBinding 会自动从 Awareness 中读取 cursor 信息并显示
                // 检查是否有光标位置（QuillBinding 会自动处理）
                if (state.cursor !== undefined) {
                  console.log(`[Yjs] 用户 ${user.name} 的光标位置:`, state.cursor);
                } else {
                  console.log(`[Yjs] 用户 ${user.name} 的光标位置未设置`);
                }
              }
            }
          });
        });
        
        // 监听 Awareness 更新事件
        awareness.on('update', (update: { added: number[], updated: number[], removed: number[] }) => {
          console.log('[Yjs] Awareness update 事件:', update);
        });
      }
      
      addLog('系统', '已启用OT算法（Yjs）和光标位置显示');
      
      // 返回清理函数
      return () => {
        // 清理用户信息更新定时器
        cleanupInterval();
        
        // 清理自动保存定时器
        if (autoSaveTimer) {
          clearInterval(autoSaveTimer);
        }
        if (saveTimeoutRef.current) {
          clearTimeout(saveTimeoutRef.current);
          saveTimeoutRef.current = null;
        }
        
        if (bindingRef.current) {
          bindingRef.current.destroy();
          bindingRef.current = null;
        }
        if (providerRef.current) {
          providerRef.current.destroy();
          providerRef.current = null;
        }
        if (ydocRef.current) {
          ydocRef.current.destroy();
          ydocRef.current = null;
        }
        if (newQuill) {
          // 移除Quill实例
          const quillContainer = newQuill.container;
          if (quillContainer) {
            const toolbar = quillContainer.parentNode?.querySelector('.ql-toolbar');
            if (toolbar) toolbar.remove();
            
            // 清空容器内容
            quillContainer.innerHTML = '';
          }
        }
        // 重置初始化标记
        quillInitializedRef.current = false;
      };
    }
     
  }, [documentData, loading, addLog, documentId, ENABLE_ONLINE_API, ENABLE_UNDO_REDO]);
  
  // 当文档ID变化时，重置初始化标记
  useEffect(() => {
    if (documentId) {
      quillInitializedRef.current = false;
      setQuill(null);
    }
  }, [documentId]);
  
  // 移除这个useEffect，因为：
  // 1. 内容已经在初始化时设置了
  // 2. 后续的变更应该通过delta应用，而不是直接设置innerHTML
  // 3. 直接设置innerHTML会导致内容重复
  // 只在文档ID变化时重新加载内容（通过重新初始化编辑器）

  // 优化保存文档函数，使用useCallback缓存
  // 移除documentData依赖，改为在函数内部使用最新的documentData值
  const saveDocument = useCallback(async (isAutoSave = false) => {
    if (!documentId) {
      message.warning('请先打开一个文档');
      return;
    }

    // 使用局部变量存储当前的documentData引用，避免闭包问题
    const currentDocData = documentData;

    // 根据 docType 决定内容来源
    let content = '';
    if (currentDocData?.docType === 'sheet' || currentDocData?.docType === 'slide' || currentDocData?.docType === 'mindmap') {
      // 对于非富文本编辑器，我们在编辑器控件中已更新 documentData.content，这里直接使用
      content = currentDocData?.content || '';
    } else {
      if (!quill) {
        message.warning('编辑器未就绪');
        return;
      }
      content = quill.root.innerHTML;
    }
    
    console.log('开始保存文档:', { documentId, contentLength: content.length, isAutoSave });
    setSaving(true);
    
    try {
      // 更新文档内容 - 这是核心功能，必须保证成功
      const updateResponse = await documentAPI.updateDocument(documentId, { content });
      
      console.log('更新文档响应:', updateResponse);
      
      // 判断文档内容是否成功更新
      const isContentSaved = updateResponse.success || (updateResponse.code === 200);
      
      // 更新最后保存时间（无论版本创建是否成功）
      if (isContentSaved) {
        const now = new Date().toLocaleString();
        setLastSavedTime(now);
      }
      
      // 创建版本（可选）- 单独的try-catch确保版本创建失败不影响文档保存状态
        let isVersionCreated = false;
        if (ENABLE_HISTORY_API && isContentSaved) {
          try {
            const versionData = {
              content,
              user: currentUserName.current,
              description: isAutoSave ? '自动保存' : '手动保存文档'
            };
            
            console.log('发送版本创建请求:', { documentId, data: versionData });
            
            const versionResponse = await documentAPI.createVersion(documentId, versionData);
            
            const versionApiResponse = versionResponse as unknown as { 
              success?: boolean; 
              data?: HistoryVersion; 
              code?: number;
              message?: string;
              error?: unknown
            };
            
            console.log('版本创建响应:', versionApiResponse);
            
            if (versionApiResponse.success && versionApiResponse.data) {
              setHistoryVersions(prev => [versionApiResponse.data as HistoryVersion, ...prev]);
              isVersionCreated = true;
            } else {
              console.warn('版本创建失败（API返回非成功状态）:', {
                success: versionApiResponse.success,
                code: versionApiResponse.code,
                message: versionApiResponse.message,
                error: versionApiResponse.error
              });
            }
          } catch (versionError: unknown) {
            const error = versionError as Error & { response?: { data?: unknown } }
            console.error('创建版本时发生异常:', {
              message: error.message,
              stack: error.stack,
              response: error.response?.data
            });
            // 版本创建失败不影响文档保存状态
          }
        }
      
      // 根据不同情况显示不同的提示
      if (isContentSaved) {
        if (!isAutoSave) {
          if (isVersionCreated || !ENABLE_HISTORY_API) {
            message.success('文档保存成功！');
          } else {
            message.success('文档内容已保存，但版本记录创建失败');
          }
        }
        addLog(currentUserName.current, isAutoSave ? '自动保存了文档' : '保存了文档');
      } else {
        // 文档内容保存失败
        const errorMessage = updateResponse.message || '保存文档失败';
        console.error('保存失败 - 业务错误:', errorMessage);
        if (!isAutoSave) {
          message.error(errorMessage);
        }
        addLog('系统', `保存文档失败: ${errorMessage}`);
      }
    } catch (error) {
      console.error('保存文档异常:', error);
      const errorMsg = error instanceof Error ? error.message : '保存文档失败，请重试';
      // 自动保存失败时不显示错误提示，避免打扰用户
      if (!isAutoSave) {
        message.error(errorMsg);
      }
      addLog('系统', `保存文档失败: ${errorMsg}`);
    } finally {
      setSaving(false);
    }
     
  }, [quill, documentId, addLog, ENABLE_HISTORY_API, documentData]);
  
  // 自动保存功能
  useEffect(() => {
    if (ENABLE_AUTO_SAVE && documentId && quill) {
      console.log('启动自动保存功能');
      // 每30秒自动保存一次
      const timer = setInterval(() => {
        console.log('触发自动保存');
        saveDocument(true);
      }, 30000);
      
      setAutoSaveTimer(timer);
      
      // 页面关闭前保存
      const handleBeforeUnload = () => {
        console.log('页面关闭前保存');
        saveDocument(true);
        // 不阻止页面关闭，但给浏览器时间完成保存
      };
      
      window.addEventListener('beforeunload', handleBeforeUnload);
      
      return () => {
        if (timer) {
          clearInterval(timer);
          console.log('清理自动保存定时器');
        }
        window.removeEventListener('beforeunload', handleBeforeUnload);
        // 清理搜索高亮（clearHighlights 在下方定义，这里通过 quill 直接清理）
        if (quill) {
          const contentLength = quill.getText().length;
          quill.formatText(0, contentLength, 'background', false, 'api');
        }
      };
    }
  }, [documentId, quill, saveDocument, ENABLE_AUTO_SAVE]);

  // 历史版本恢复功能
  const restoreFromVersion = useCallback(async (version: HistoryVersion) => {
    if (!documentId || !version) {
      message.warning('请选择一个有效的版本');
      return;
    }
    
    try {
      // 先保存当前版本
      await saveDocument(false);
      
      // 恢复到选定版本
      const restoreResponse = await documentAPI.restoreVersion(documentId, version.id);
      const restoreApiResponse = restoreResponse as unknown as { success?: boolean; data?: { content: string }; code?: number };
      
      if (restoreApiResponse.success && restoreApiResponse.data) {
        const { content } = restoreApiResponse.data;
        
        // 更新编辑器内容
        if (documentData?.docType === 'sheet' || documentData?.docType === 'slide' || documentData?.docType === 'mindmap') {
          setDocumentData(prev => prev ? { ...prev, content } : prev);
        } else if (quill) {
          quill.clipboard.dangerouslyPasteHTML(content);
        }
        
        // 创建新的版本记录
        if (ENABLE_HISTORY_API) {
          await documentAPI.createVersion(documentId, {
            content,
            user: currentUserName.current,
            description: `恢复到版本 ${version.version}`
          });
          
          // 重新加载版本历史
          const versionsResponse = await documentAPI.getDocumentVersions(documentId);
          const versionsApiResponse = versionsResponse as unknown as { success?: boolean; data?: HistoryVersion[]; code?: number };
          if (versionsApiResponse.success && versionsApiResponse.data) {
            setHistoryVersions(versionsApiResponse.data);
          }
        }
        
        message.success(`已成功恢复到版本 ${version.version}`);
        addLog(currentUserName.current, `恢复文档到版本 ${version.version}`);
        setShowHistory(false);
      } else {
        message.error('恢复版本失败');
      }
    } catch (error) {
      console.error('恢复版本失败:', error);
      message.error('恢复版本失败，请重试');
    } finally {
      setRestoringVersion(null);
    }
  }, [documentId, quill, documentData, saveDocument, addLog, ENABLE_HISTORY_API]);

  // 处理版本ID的恢复函数
  const restoreVersion = useCallback(async (versionId: string) => {
    try {
      // 设置恢复中的版本ID
      setRestoringVersion(versionId);
      
      // 查找对应的版本对象
      const version = historyVersions.find(v => v.id === versionId);
      if (version) {
        await restoreFromVersion(version);
      } else {
        message.error('未找到指定的版本');
        setRestoringVersion(null);
      }
    } catch (error) {
      console.error('恢复版本失败:', error);
      message.error('恢复版本失败，请重试');
      setRestoringVersion(null);
    }
  }, [historyVersions, restoreFromVersion]);
  
  const editComment = useCallback(async (commentId: string, newContent: string) => {
    if (!documentId || !commentId || !newContent.trim()) {
      message.warning('请输入有效的评论内容');
      return;
    }
    
    try {
      const response = await documentAPI.updateComment(documentId, commentId, { content: newContent });
      const commentApiResponse = response as unknown as { success?: boolean; data?: Comment; code?: number };
      
      if (commentApiResponse.success && commentApiResponse.data) {
        const updatedComment = commentApiResponse.data;
        // 更新本地评论状态
        setComments(prev => prev.map(c => {
          if (c.id === commentId) return updatedComment;
          // 检查是否是回复
          if (c.replies) {
            return {
              ...c,
              replies: c.replies.map(r => r.id === commentId ? updatedComment : r)
            };
          }
          return c;
        }));
        
        // 通知其他用户
        if (socketRef.current && socketRef.current.connected) {
          socketRef.current.emit('comment-updated', { documentId, comment: updatedComment });
        }
        
        message.success('评论已更新');
        addLog(currentUserName.current, '更新了评论');
      } else {
        message.error('更新评论失败');
      }
    } catch (error) {
      console.error('更新评论失败:', error);
      message.error('更新评论失败，请重试');
    }
  }, [documentId, addLog]);
  
  // 评论删除功能
  const deleteComment = useCallback(async (commentId: string) => {
    if (!documentId || !commentId) {
      return;
    }
    
    try {
      const response = await documentAPI.deleteComment(documentId, commentId);
      const deleteApiResponse = response as unknown as { success?: boolean; code?: number };
      
      if (deleteApiResponse.success) {
        // 更新本地评论状态
        setComments(prev => {
          // 移除顶级评论
          const filtered = prev.filter(c => c.id !== commentId);
          // 移除回复中的评论
          return filtered.map(c => {
            if (c.replies) {
              return {
                ...c,
                replies: c.replies.filter(r => r.id !== commentId)
              };
            }
            return c;
          });
        });
        
        // 通知其他用户
        if (socketRef.current && socketRef.current.connected) {
          socketRef.current.emit('comment-deleted', { documentId, commentId });
        }
        
        message.success('评论已删除');
        addLog(currentUserName.current, '删除了评论');
      } else {
        message.error('删除评论失败');
      }
    } catch (error) {
      console.error('删除评论失败:', error);
      message.error('删除评论失败，请重试');
    }
  }, [documentId, addLog]);

  const handleEditCommentSubmit = useCallback(async () => {
    if (!editingCommentId) {
      message.warning('请选择要编辑的评论');
      return;
    }
    if (!editingCommentContent.trim()) {
      message.warning('请填写评论内容');
      return;
    }
    try {
      await editComment(editingCommentId, editingCommentContent.trim());
      setShowEditCommentModal(false);
      setEditingCommentId(null);
      setEditingCommentContent('');
    } catch (error) {
      console.error('编辑评论失败:', error);
    }
  }, [editComment, editingCommentContent, editingCommentId]);

  const handleEditCommentCancel = useCallback(() => {
    setShowEditCommentModal(false);
    setEditingCommentId(null);
    setEditingCommentContent('');
  }, []);
  
  // 清除所有搜索高亮
  const clearHighlights = useCallback(() => {
    if (!quill) return;
    
    // 清除所有文本的背景高亮
    const contentLength = quill.getText().length;
    quill.formatText(0, contentLength, 'background', false, 'api');
  }, [quill]);
  
  // 高亮搜索结果
  const highlightSearchResult = useCallback((index: number, length: number) => {
    if (!quill) return;
    
    // 清除之前的选择
    quill.setSelection(null);
    
    // 高亮当前匹配项
    quill.formatText(index, length, 'background', '#ffeb3b', 'api');
    
    // 再次设置选择范围以便用户看到
    quill.setSelection(index, length, 'api');
    
    // 滚动到选中位置
    const container = quill.container;
    const line = container.querySelector(`[data-index="${Math.floor(index / 100)}"]`);
    if (line) {
      line.scrollIntoView({ behavior: 'smooth', block: 'center' });
    }
  }, [quill]);
  
  // 内容搜索功能
  const searchContent = useCallback((term: string) => {
    if (!term.trim() || !quill) {
      setSearchResults([]);
      setCurrentSearchIndex(-1);
      setIsSearching(false);
      clearHighlights();
      return;
    }
    
    // 清除之前的高亮
    clearHighlights();
    
    const content = quill.getText();
    const results: { index: number; text: string }[] = [];
    let pos = 0;
    
    while ((pos = content.toLowerCase().indexOf(term.toLowerCase(), pos)) !== -1) {
      // 提取匹配项前后的文本作为上下文
      const start = Math.max(0, pos - 10);
      const end = Math.min(content.length, pos + term.length + 10);
      const context = content.substring(start, end);
      
      results.push({
        index: pos,
        text: context
      });
      
      pos += term.length;
    }
    
    setSearchResults(results);
    setCurrentSearchIndex(results.length > 0 ? 0 : -1);
    setIsSearching(true);
    
    // 高亮第一个匹配项
    if (results.length > 0) {
      highlightSearchResult(results[0].index, term.length);
    }
  }, [quill, clearHighlights, highlightSearchResult]);
  
  // 导航到下一个搜索结果
  const navigateToNextResult = useCallback(() => {
    if (searchResults.length === 0) return;
    
    const nextIndex = (currentSearchIndex + 1) % searchResults.length;
    setCurrentSearchIndex(nextIndex);
    highlightSearchResult(searchResults[nextIndex].index, searchTerm.length);
  }, [searchResults, currentSearchIndex, searchTerm, highlightSearchResult]);
  
  // 导航到上一个搜索结果
  const navigateToPrevResult = useCallback(() => {
    if (searchResults.length === 0) return;
    
    const prevIndex = (currentSearchIndex - 1 + searchResults.length) % searchResults.length;
    setCurrentSearchIndex(prevIndex);
    highlightSearchResult(searchResults[prevIndex].index, searchTerm.length);
  }, [searchResults, currentSearchIndex, searchTerm, highlightSearchResult]);
  
  // 文档导出功能
  const exportDocument = useCallback(() => {
    if (!documentId || !documentData) {
      message.warning('请先打开一个文档');
      return;
    }
    
    try {
      let content = '';
      let mimeType = '';
      let extension = '';
      
      if (documentData.docType === 'sheet' || documentData.docType === 'slide' || documentData.docType === 'mindmap') {
        // 对于特殊类型文档，导出JSON格式
        content = documentData.content || '';
        mimeType = 'application/json';
        extension = 'json';
      } else if (quill) {
        // 对于富文本文档，导出HTML
        content = quill.root.innerHTML;
        mimeType = 'text/html';
        extension = 'html';
      }
      
      // 创建Blob并下载
      const blob = new Blob([content], { type: mimeType });
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = `${documentData.name}.${extension}`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
      
      message.success('文档导出成功');
      addLog(currentUserName.current, `导出了文档 (${extension})`);
    } catch (error) {
      console.error('导出文档失败:', error);
      message.error('导出文档失败，请重试');
    }
  }, [documentId, documentData, quill, addLog]);
  
  // 离线编辑支持
  useEffect(() => {
    // 监听在线/离线状态变化
    const handleOnlineStatusChange = () => {
      setOfflineMode(!navigator.onLine);
      if (navigator.onLine) {
        message.success('已恢复网络连接，同步中...');
        // 重新连接时自动保存
        if (documentId) {
          saveDocument(true);
        }
      } else {
        message.warning('网络连接已断开，进入离线编辑模式');
      }
    };
    
    window.addEventListener('online', handleOnlineStatusChange);
    window.addEventListener('offline', handleOnlineStatusChange);
    
    // 初始检查
    setOfflineMode(!navigator.onLine);
    
    return () => {
      window.removeEventListener('online', handleOnlineStatusChange);
      window.removeEventListener('offline', handleOnlineStatusChange);
    };
  }, [documentId, saveDocument]);
  
  // 查看历史版本（预留，暂未使用）
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const viewHistory = useCallback((version: HistoryVersion) => {
    setSelectedVersion(version);
  }, []);

  // 回复评论（预留，暂未使用）
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const replyToComment = useCallback((commentId: string) => {
    setReplyTo(commentId);
  }, []);

  // 优化提交评论函数，使用useCallback缓存
  const submitComment = useCallback(async () => {
    if (commentInput.trim() && documentId) {
      try {
        if (ENABLE_COMMENTS_API) {
          const response = await documentAPI.createComment(documentId, {
            user: currentUserName.current,
            avatar: currentUserName.current.charAt(0),
            color: currentUserColor.current,
            content: commentInput,
            position: quill?.getSelection()?.index || 0,
            parentId: replyTo || undefined
          });
          
          const commentApiResponse = response as unknown as { success?: boolean; data?: Comment; code?: number };
          if (commentApiResponse.success && commentApiResponse.data) {
            const newComment = commentApiResponse.data;
            // 先更新本地状态...
            if (replyTo) {
              setComments(prev => {
                const parentComment = prev.find(c => c.id === replyTo);
                if (parentComment?.replies?.some(r => r.id === newComment.id)) {
                  return prev;
                }
                return prev.map(comment => {
                  if (comment.id === replyTo) {
                    return {
                      ...comment,
                      replies: [...(comment.replies || []), newComment]
                    };
                  }
                  return comment;
                });
              });
              setReplyTo(null);
            } else {
              setComments(prev => {
                if (prev.some(c => c.id === newComment.id)) {
                  return prev;
                }
                return [newComment, ...prev];
              });
            }
            if (socketRef.current && socketRef.current.connected) {
              socketRef.current.emit('comment-added', { documentId, comment: newComment });
            }
            setCommentInput('');
            addLog(currentUserName.current, '添加了评论');
          }
        } else {
          // 如果后端 API 失败，显示错误信息
          message.error('添加评论失败，请稍后重试');
        }
      } catch (error) {
        console.error('添加评论失败:', error);
        addLog('系统', '添加评论失败');
      }
    }
  }, [commentInput, replyTo, documentId, quill, addLog, ENABLE_COMMENTS_API]);

  // 格式化时间（预留，暂未使用）
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const formatTime = useCallback((timestamp: number) => {
    return new Date(timestamp).toLocaleString();
  }, []);

  const themeStore = useThemeStore();
  const isDark = themeStore.getEffectiveTheme() === 'dark';

  const UserItem: React.FC<{ user: OnlineUserType }> = memo(({ user }) => (
    <div className={`flex items-center space-x-2 p-2 ${isDark ? 'hover:bg-gray-700' : 'hover:bg-gray-50'} rounded`}>
      <div className={`w-7 h-7 rounded-full ${user.color} flex items-center justify-center text-white text-xs font-bold`}>
        {user.avatar}
      </div>
      <div className="flex-1">
        <div className={`text-sm font-medium ${isDark ? 'text-gray-100' : ''}`}>{user.name}</div>
      </div>
    </div>
  ));
  UserItem.displayName = 'UserItem';

  return (
    <div className={`min-h-screen p-6 transition-colors duration-300 ${isDark ? 'bg-gray-900 text-gray-100' : 'bg-gray-50 text-gray-900'}`}>
      <div className="max-w-7xl mx-auto space-y-6">
        <div className="mb-6">
          <h2 className={`text-2xl font-bold ${isDark ? 'text-gray-100' : 'text-gray-800'}`}>在线协作编辑器</h2>
          <p className={`mt-1 ${isDark ? 'text-gray-400' : 'text-gray-500'}`}>支持多人实时协作编辑、历史版本管理和评论功能</p>
        </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
        {/* 主编辑区 */}
        <div className="lg:col-span-2 space-y-4">
          {/* 顶部工具栏 */}
          <div className={`${isDark ? 'bg-gray-800 border-gray-700' : 'bg-white'} rounded-lg shadow p-4 border ${isDark ? 'border-gray-700' : ''}`}>
            <div className="flex items-center justify-between">
              <div className="flex items-center space-x-3">
                <FileText className="text-blue-600" size={20} />
                <h3 className={`font-semibold ${isDark ? 'text-gray-100' : ''}`}>{documentData?.name || '文档'}</h3>
                <Badge dot color="blue" />
              </div>
              
              <div className="flex flex-wrap items-center gap-3">
                <div className="flex items-center space-x-3">
                  <span className={`text-sm font-medium ${isDark ? 'text-gray-300' : 'text-gray-700'} flex items-center gap-1`}>
                    <Users size={16} />
                    在线协作：
                  </span>
                  
                  <div className="flex items-center space-x-2">
                <span className={`w-2 h-2 rounded-full ${wsConnected ? 'bg-green-500 animate-pulse' : 'bg-red-500'}`}></span>
                <span className={`text-sm ${isDark ? 'text-gray-300' : 'text-gray-600'}`}>
                  {offlineMode ? '离线编辑模式' : (wsConnected ? '实时连接正常' : '连接中断，重连中...')}
                </span>
                {ENABLE_AUTO_SAVE && (
                  <span className={`ml-2 text-xs ${isDark ? 'text-gray-400' : 'text-gray-500'}`}>
                    自动保存中
                  </span>
                )}
              </div>
                  
                  {/* 在线用户列表 */}
                  <div className="flex items-center space-x-2">
                    <span className={`text-sm ${isDark ? 'text-gray-400' : 'text-gray-500'}`}>在线：</span>
                    <div className="flex -space-x-2">
                      {onlineUsers.map((user, index) => (
                      <Tooltip key={user.id || `${user.name}-${index}`} title={user.name}>
                          <div
                            className={`w-8 h-8 rounded-full ${user.color} flex items-center justify-center text-white text-xs font-bold border-2 border-white shadow-sm hover:z-10 transition-transform hover:scale-110`}
                          >
                            {user.avatar}
                          </div>
                        </Tooltip>
                      ))}
                    </div>
                  </div>
                </div>
                <span className="text-sm text-gray-500">({onlineUsers.length}人)</span>
              </div>

              <div className="flex items-center space-x-2">
                <span className={`w-2 h-2 rounded-full ${wsConnected ? 'bg-green-500 animate-pulse' : 'bg-red-500'}`}></span>
                <span className={`text-sm ${isDark ? 'text-gray-300' : 'text-gray-600'}`}>
                  {wsConnected ? 'WebSocket已连接' : '正在重连...'}
                </span>
              </div>
            </div>
          </div>

          {/* 富文本编辑器 */}
          <div className={`${isDark ? 'bg-gray-800 border-gray-700' : 'bg-white'} rounded-lg shadow p-4 border ${isDark ? 'border-gray-700' : ''}`}>
            {loading ? (
              <div className="flex items-center justify-center min-h-[500px]">
                <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mr-3"></div>
                <span className="text-gray-600">加载文档中...</span>
              </div>
            ) : (
              // 根据 docType 切换编辑器
              <div className="min-h-[500px]">
                {documentData?.docType === 'sheet' ? (
                  <SheetEditor
                    value={documentData?.content}
                    onChange={(val) => setDocumentData(prev => prev ? { ...prev, content: val } : prev)}
                  />
                ) : documentData?.docType === 'slide' ? (
                  <SlideEditor
                    value={documentData?.content}
                    onChange={(val) => setDocumentData(prev => prev ? { ...prev, content: val } : prev)}
                  />
                ) : documentData?.docType === 'mindmap' ? (
                  <MindmapEditor
                    value={documentData?.content}
                    onChange={(val) => setDocumentData(prev => prev ? { ...prev, content: val } : prev)}
                  />
                ) : (
                  <div ref={editorRef} className="min-h-[500px]"></div>
                )}
              </div>
            )}
            
            <div className="mt-4">
                {/* 搜索功能区域 */}
                {ENABLE_SEARCH && (
                  <div className="mb-3 flex items-center space-x-2">
                    <AntInput
                      placeholder="搜索内容..."
                      value={searchTerm}
                      onChange={(e) => setSearchTerm(e.target.value)}
                      onPressEnter={() => searchContent(searchTerm)}
                      className="w-64"
                      allowClear
                    />
                    <Button onClick={() => searchContent(searchTerm)}>搜索</Button>
                    {isSearching && searchResults.length > 0 && (
                      <div className="flex items-center space-x-1">
                        <Button size="small" onClick={navigateToPrevResult}>上一个</Button>
                        <span className="text-sm">{currentSearchIndex + 1}/{searchResults.length}</span>
                        <Button size="small" onClick={navigateToNextResult}>下一个</Button>
                        <Button size="small" type="link" onClick={() => {
                          setIsSearching(false);
                          setSearchResults([]);
                          setCurrentSearchIndex(-1);
                          setSearchTerm('');
                          clearHighlights();
                        }}>清除</Button>
                      </div>
                    )}
                  </div>
                )}
                
                {/* 功能按钮区域 */}
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <div className="space-x-2">
                    <Button 
                      type="primary" 
                      onClick={() => saveDocument(false)}
                      className="bg-blue-600 hover:bg-blue-700"
                      icon={<Save size={16} />}
                      loading={saving}
                      disabled={saving}
                    >
                      {saving ? '保存中...' : '保存文档'}
                    </Button>
                    {ENABLE_HISTORY_API && (
                      <Button 
                        onClick={() => setShowHistory(true)}
                        icon={<History size={16} />}
                      >
                        历史版本
                      </Button>
                    )}
                    {ENABLE_COMMENTS_API && (
                      <Button 
                        onClick={() => setShowComments(true)}
                        icon={<MessageSquare size={16} />}
                      >
                        查看评论
                      </Button>
                    )}
                    {ENABLE_EXPORT && (
                      <Button 
                        onClick={exportDocument}
                        icon={<FileText size={16} />}
                      >
                        导出文档
                      </Button>
                    )}
                    {ENABLE_ONLINE_API && (
                      <Button 
                        onClick={() => setShowOnlineUsers(true)}
                        icon={<Users size={16} />}
                      >
                        在线人员
                      </Button>
                    )}
                  </div>
                  <div className="flex items-center space-x-3">
                    <div className="flex items-center">
                      <span className={`mr-2 text-sm ${isDark ? 'text-gray-300' : 'text-gray-600'}`}>自动保存</span>
                      <Switch 
                        checked={ENABLE_AUTO_SAVE}
                        onChange={(checked) => {
                          setEnableAutoSave(checked);
                          // 保存到localStorage以便持久化
                          try {
                            localStorage.setItem('document_auto_save', JSON.stringify(checked));
                          } catch (error) {
                            console.warn('保存自动保存设置失败:', error);
                          }
                          addLog(currentUserName.current, checked ? '开启了自动保存' : '关闭了自动保存');
                          message.info(checked ? '自动保存已开启' : '自动保存已关闭');
                        }}
                      />
                    </div>
                    <span className={`text-sm ${isDark ? 'text-gray-400' : 'text-gray-500'}`}>
                      最后保存：{lastSavedTime}
                    </span>
                  </div>
                </div>
            </div>
          </div>

          {/* 技术说明 */}
          <div className={`${isDark ? 'bg-gray-800 border-gray-700' : 'bg-white'} rounded-lg shadow p-6 border ${isDark ? 'border-gray-700' : ''}`}>
            <h3 className={`text-lg font-semibold mb-4 ${isDark ? 'text-gray-100' : ''}`}>🔥 技术实现说明</h3>
            <div className="space-y-3 text-sm">
              <div className={`p-3 ${isDark ? 'bg-blue-900/30' : 'bg-blue-50'} rounded-lg`}>
                <strong className={isDark ? 'text-blue-200' : 'text-blue-800'}>实时通信：</strong>
                <p className={`${isDark ? 'text-gray-300' : 'text-gray-700'} mt-1`}>
                  使用Socket.io建立WebSocket连接，实现多人实时协作编辑。
                  延迟&lt;100ms，支持断线重连。
                </p>
              </div>
              
              <div className={`p-3 ${isDark ? 'bg-green-900/30' : 'bg-green-50'} rounded-lg`}>
                <strong className={isDark ? 'text-green-200' : 'text-green-800'}>冲突解决：</strong>
                <p className={`${isDark ? 'text-gray-300' : 'text-gray-700'} mt-1`}>
                  使用OT算法处理冲突。当A在位置5插入，B在位置3插入时，
                  自动调整位置，保证最终一致性。
                </p>
              </div>
            </div>
          </div>
        </div>

        {/* 右侧面板 */}
        <div className="space-y-4">
          {/* 实时操作日志 */}
          <div className={`${isDark ? 'bg-gray-800 border-gray-700' : 'bg-white'} rounded-lg shadow p-4 border ${isDark ? 'border-gray-700' : ''}`}>
            <h3 className="font-semibold mb-3">📝 实时操作日志</h3>
            <div className="space-y-2 max-h-64 overflow-y-auto">
              {editLogs.map(log => (
                <div key={log.id} className={`p-2 ${isDark ? 'bg-gray-700' : 'bg-gray-50'} rounded text-sm`}>
                  <div className={`font-medium ${isDark ? 'text-gray-100' : 'text-gray-800'}`}>{log.user}</div>
                  <div className={isDark ? 'text-gray-300' : 'text-gray-600'}>{log.action}</div>
                  <div className={`text-xs ${isDark ? 'text-gray-500' : 'text-gray-400'} mt-1`}>{log.time}</div>
                </div>
              ))}
            </div>
          </div>

          {/* 在线人员 */}
          <div className={`${isDark ? 'bg-gray-800 border-gray-700' : 'bg-white'} rounded-lg shadow p-4 border ${isDark ? 'border-gray-700' : ''}`}>
            <h3 className="font-semibold mb-3">👥 在线人员</h3>
            <div className="space-y-2">
              {onlineUsers.length > 0 ? (
                onlineUsers.map((user, index) => (
                  <UserItem key={user.id || `${user.name}-${index}`} user={user} />
                ))
              ) : (
                <div className={`text-sm ${isDark ? 'text-gray-400' : 'text-gray-500'} text-center py-4`}>暂无其他在线用户</div>
              )}
            </div>
          </div>

          {/* 应用场景 */}
          <div className={`${isDark ? 'bg-gray-800 border-gray-700' : 'bg-white'} rounded-lg shadow p-4 border ${isDark ? 'border-gray-700' : ''}`}>
            <h3 className="font-semibold mb-3">💼 应用场景</h3>
            <div className="space-y-2 text-sm">
              <div className={`p-2 ${isDark ? 'bg-yellow-900/30' : 'bg-yellow-50'} rounded`}>
                <strong className={isDark ? 'text-yellow-200' : ''}>📦 商品详情</strong>
                <p className={`${isDark ? 'text-gray-300' : 'text-gray-600'} text-xs mt-1`}>多人协同编辑</p>
              </div>
              <div className={`p-2 ${isDark ? 'bg-blue-900/30' : 'bg-blue-50'} rounded`}>
                <strong className={isDark ? 'text-blue-200' : ''}>🎉 活动方案</strong>
                <p className={`${isDark ? 'text-gray-300' : 'text-gray-600'} text-xs mt-1`}>大促筹备协作</p>
              </div>
            </div>
          </div>
        </div>
      </div>
      </div>

      {/* 历史版本管理 Drawer */}
      <Drawer
        title="历史版本"
        placement="right"
        onClose={() => setShowHistory(false)}
        open={showHistory}
        width={500}
        className={isDark ? 'dark' : ''}
      >
        <List
          dataSource={historyVersions}
          loading={loading}
          locale={{ emptyText: '暂无历史版本' }}
          renderItem={(version) => (
            <List.Item
              className={`cursor-pointer hover:bg-gray-50 ${isDark ? 'hover:bg-gray-700' : ''}`}
              actions={[
                <Button
                  key="view"
                  size="small"
                  onClick={() => {
                    setSelectedVersion(version);
                    message.info(`查看版本 ${version.version}：${version.description || '无描述'}`);
                  }}
                >
                  查看
                </Button>,
                <Button
                  key="restore"
                  size="small"
                  type="primary"
                  loading={restoringVersion === version.id}
                  onClick={(e) => {
                    e.stopPropagation();
                    Modal.confirm({
                      title: '恢复版本确认',
                      content: '确定要恢复到此版本吗？当前未保存的内容将丢失。',
                      onOk: () => restoreVersion(version.id),
                    });
                  }}
                >
                  恢复
                </Button>
              ]}
            >
              <List.Item.Meta
                avatar={
                  <Avatar style={{ backgroundColor: '#1890ff' }}>
                    {version.user?.charAt(0) || 'V'}
                  </Avatar>
                }
                title={
                  <div className="flex items-center justify-between">
                    <span>版本 {version.version}</span>
                    <span className={`text-xs ${isDark ? 'text-gray-400' : 'text-gray-500'}`}>
                      {new Date(version.timestamp).toLocaleString()}
                    </span>
                  </div>
                }
                description={
                  <div>
                    <div className={isDark ? 'text-gray-300' : ''}>
                      {version.description || '无描述'}
                    </div>
                    <div className={`text-xs mt-1 ${isDark ? 'text-gray-500' : 'text-gray-400'}`}>
                      创建人：{version.user || '未知'}
                    </div>
                  </div>
                }
              />
            </List.Item>
          )}
        />
      </Drawer>

      {/* 评论功能 Drawer */}
      <Drawer
        title="评论"
        placement="right"
        onClose={() => {
          setShowComments(false);
          setReplyTo(null);
        }}
        open={showComments}
        width={500}
        className={isDark ? 'dark' : ''}
        extra={
          <div className="flex items-center space-x-2">
            <AntInput
              placeholder="输入评论..."
              value={commentInput}
              onChange={(e) => setCommentInput(e.target.value)}
              onPressEnter={submitComment}
              className="w-64"
            />
            <Button type="primary" onClick={submitComment} disabled={!commentInput.trim()}>
              发送
            </Button>
          </div>
        }
      >
        <div className="space-y-4">
          {/* 评论输入框 */}
          <div className={`p-4 ${isDark ? 'bg-gray-800' : 'bg-gray-50'} rounded-lg`}>
            <AntInput.TextArea
              placeholder={replyTo ? '回复评论...' : '输入评论...'}
              value={commentInput}
              onChange={(e) => setCommentInput(e.target.value)}
              rows={3}
              className={isDark ? 'bg-gray-700 text-gray-100' : ''}
            />
            {replyTo && (
              <div className="mt-2 flex items-center justify-between">
                <span className={`text-sm ${isDark ? 'text-gray-400' : 'text-gray-500'}`}>
                  回复：{comments.find(c => c.id === replyTo)?.user || '未知用户'}
                </span>
                <Button size="small" onClick={() => setReplyTo(null)}>
                  取消
                </Button>
              </div>
            )}
            <div className="mt-2 flex justify-end">
              <Button type="primary" onClick={submitComment} disabled={!commentInput.trim()}>
                发送评论
              </Button>
            </div>
          </div>

          {/* 评论列表 */}
          <List
            dataSource={comments}
            loading={loading}
            locale={{ emptyText: '暂无评论，快来发表第一条评论吧！' }}
            renderItem={(comment) => (
              <List.Item
                className="px-0!"
                key={comment.id || (comment as { _id?: string })._id || `${comment.user}-${comment.timestamp}`}
              >
                <div className={`w-full p-4 ${isDark ? 'bg-gray-800' : 'bg-white'} rounded-lg border ${isDark ? 'border-gray-700' : 'border-gray-200'}`}>
                  <div className="flex items-start space-x-3">
                    <Avatar style={{ backgroundColor: comment.color || '#1890ff' }}>
                      {comment.avatar || comment.user?.charAt(0) || 'U'}
                    </Avatar>
                    <div className="flex-1">
                      <div className="flex items-center justify-between mb-2">
                        <span className={`font-medium ${isDark ? 'text-gray-100' : ''}`}>
                          {comment.user || '未知用户'}
                        </span>
                        <span className={`text-xs ${isDark ? 'text-gray-500' : 'text-gray-400'}`}>
                          {new Date(comment.timestamp).toLocaleString()}
                        </span>
                      </div>
                      <div className={`mb-2 ${isDark ? 'text-gray-300' : 'text-gray-700'}`}>
                        {comment.content}
                      </div>
                      <div className="flex items-center space-x-2">
                        <Button
                          size="small"
                          type="link"
                          onClick={() => {
                            setReplyTo(comment.id);
                            setShowComments(true);
                          }}
                        >
                          回复
                        </Button>
                        {ENABLE_COMMENTS_API && comment.isEditable && (
                          <>
                            <Button
                              size="small"
                              type="link"
                              onClick={() => {
                                setEditingCommentId(comment.id);
                                setEditingCommentContent(comment.content || '');
                                setShowEditCommentModal(true);
                              }}
                            >
                              编辑
                            </Button>
                            <Button
                              size="small"
                              type="link"
                              danger
                              onClick={() => {
                                Modal.confirm({
                                  title: '删除评论确认',
                                  content: '确定要删除这条评论吗？',
                                  onOk: () => deleteComment(comment.id),
                                });
                              }}
                            >
                              删除
                            </Button>
                          </>
                        )}
                      </div>
                      {/* 回复列表 */}
                      {comment.replies && comment.replies.length > 0 && (
                        <div className={`mt-3 ml-4 pl-4 border-l-2 ${isDark ? 'border-gray-700' : 'border-gray-200'}`}>
                          {comment.replies.map((reply) => (
                            <div
                              key={reply.id || (reply as { _id?: string })._id || `${reply.user}-${reply.timestamp}`}
                              className={`mb-3 p-3 ${isDark ? 'bg-gray-700' : 'bg-gray-50'} rounded`}
                            >
                              <div className="flex items-center space-x-2 mb-1">
                                <Avatar size="small" style={{ backgroundColor: reply.color || '#52c41a' }}>
                                  {reply.avatar || reply.user?.charAt(0) || 'U'}
                                </Avatar>
                                <span className={`text-sm font-medium ${isDark ? 'text-gray-200' : ''}`}>
                                  {reply.user || '未知用户'}
                                </span>
                                <span className={`text-xs ${isDark ? 'text-gray-500' : 'text-gray-400'}`}>
                                  {new Date(reply.timestamp).toLocaleString()}
                                </span>
                                {ENABLE_COMMENTS_API && reply.isEditable && (
                                  <>
                                    <Button
                                      size="small"
                                      type="link"
                                      onClick={() => {
                                        const targetId = reply.id || (reply as { _id?: string })._id;
                                        if (targetId) {
                                          setEditingCommentId(targetId);
                                          setEditingCommentContent(reply.content || '');
                                          setShowEditCommentModal(true);
                                        } else {
                                          message.warning('无法获取回复ID，无法编辑');
                                        }
                                      }}
                                    >
                                      编辑
                                    </Button>
                                    <Button
                                      size="small"
                                      type="link"
                                      danger
                                      onClick={() => {
                                        const targetId = reply.id || (reply as { _id?: string })._id;
                                        if (!targetId) {
                                          message.warning('无法获取回复ID，无法删除');
                                          return;
                                        }
                                        Modal.confirm({
                                          title: '删除回复确认',
                                          content: '确定要删除这条回复吗？',
                                          onOk: () => deleteComment(targetId),
                                        });
                                      }}
                                    >
                                      删除
                                    </Button>
                                  </>
                                )}
                              </div>
                              <div className={isDark ? 'text-gray-300' : 'text-gray-700'}>
                                {reply.content}
                              </div>
                            </div>
                          ))}
                        </div>
                      )}
                    </div>
                  </div>
                </div>
              </List.Item>
            )}
          />
        </div>
      </Drawer>
      <Modal
        title="编辑评论"
        open={showEditCommentModal}
        okText="保存"
        cancelText="取消"
        okButtonProps={{ disabled: !editingCommentContent.trim() }}
        onOk={handleEditCommentSubmit}
        onCancel={handleEditCommentCancel}
      >
        <AntInput.TextArea
          value={editingCommentContent}
          onChange={(e) => setEditingCommentContent(e.target.value)}
          rows={4}
          placeholder="请输入评论内容"
        />
      </Modal>
      {/* 在线用户列表 Drawer */}
      <Drawer
        title="在线人员"
        placement="right"
        onClose={() => setShowOnlineUsers(false)}
        open={showOnlineUsers}
        width={400}
        className={isDark ? 'dark' : ''}
      >
        <List
          dataSource={onlineUsers}
          locale={{ emptyText: '暂无其他在线用户' }}
          renderItem={(user) => (
            <List.Item className="px-0">
              <List.Item.Meta
                avatar={
                  <Avatar style={{ backgroundColor: user.color || '#1890ff' }}>
                    {user.avatar || user.name?.charAt(0) || 'U'}
                  </Avatar>
                }
                title={
                  <div className="flex items-center">
                    <span className={isDark ? 'text-gray-100' : ''}>{user.name || '未知用户'}</span>
                    {user.id === currentUserId.current && (
                      <Badge
                        status="success"
                        text="您"
                        className="ml-2"
                      />
                    )}
                  </div>
                }
                description={
                  <div className={`text-xs ${isDark ? 'text-gray-400' : 'text-gray-500'}`}>
                    {user.cursorPosition !== undefined && user.cursorPosition >= 0 
                      ? `当前位置: 第 ${user.cursorPosition} 个字符` 
                      : '正在浏览文档'}
                  </div>
                }
              />
            </List.Item>
          )}
        />
      </Drawer>
    </div>
  )
}

export default DocumentCollab